package org.game.module.rolebo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.xiaoleilu.hutool.util.MapUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.cfg.RoleCfg;
import org.cfg.RoomCfg;
import org.cfg.cache.RoomCfgCache;
import org.constant.*;
import org.error.GameErrorCode;
import org.game.constant.SessionConstent;
import org.game.db.bean.Item;
import org.game.db.bean.Player;
import org.game.db.bean.Role;
import org.game.db.cache.ItemCache;
import org.game.db.cache.RoleCache;
import org.game.db.vo.DressVO;
import org.game.db.vo.RoomVO;
import org.game.log.builder.LogDsp;
import org.game.log.dsp.GoodsDsp;
import org.game.manager.ItemManager;
import org.game.manager.RoleManager;
import org.game.module.EnterGameHandler;
import org.game.msgBuilder.ItemMsgBuilder;
import org.game.msgBuilder.RoleMsgBuilder;
import org.game.plugin.event.GameEvent;
import org.game.plugin.event.GameEventPlugin;
import org.game.protobuf.c2s.C2SRoleMsg;
import org.game.protobuf.c2s.C2SRoleMsg.Donate;
import org.game.protobuf.c2s.C2SRoleMsg.Dress;
import org.game.protobuf.c2s.C2SRoleMsg.SwitchRole;
import org.game.protobuf.s2c.S2CItemMsg;
import org.game.protobuf.s2c.S2CRoleMsg.RoleInfoList;
import org.game.protobuf.s2c.S2CRoleMsg.RoleStatusInfo;
import org.game.protobuf.s2c.S2CRoleMsg.SwitchRoleResult;
import org.game.protobuf.s2c.S2CShareMsg.ChangeType;
import org.game.util.ProtoUnit;

import com.google.common.collect.Maps;
import com.sojoys.artifact.exception.AbstractLogicModelException;
import com.sojoys.artifact.factory.session.ISession;
import com.sojoys.artifact.tools.ToolError;

/**
 * @author : DengYing
 * @CreateDate : 2017年8月21日 上午11:34:06
 * @Description ：Please describe this document
 */
public class RoleBOImpl implements RoleBO, EnterGameHandler {
	@Override
	public void enterGame(Player player) {
		
	}

	@Override
	public byte[] getRoles(ISession session) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);
		List<Role> roles = player.getRolesFkPlayerId();
		RoleInfoList roleInfoList = RoleMsgBuilder.createRoleInfoList(ChangeType.DEFAULT, roles);
		return ProtoUnit.toByte(roleInfoList);
	}
	
	@Override
	public byte[] donate(ISession session, Donate msg) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);

		long roleId= Long.valueOf(msg.getRoleId());
		Role role = RoleCache.me().getById(roleId);

		ToolError.isAndTrue(GameErrorCode.NOT_FOND_ROLE,"精灵未找到", role==null);
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"好感度临界点，不能送礼", role.getRoleProxy().isCriticalPoint());
		ToolError.isAndTrue(GameErrorCode.GIFT_NOT_UNLOCK,"礼品没有解锁", !role.getUnlockGift().contains(msg.getItemCid()));
		
		Map<Integer, Integer> goods = Maps.newHashMapWithExpectedSize(1);
		goods.put(msg.getItemCid(), msg.getNum());
		
		ToolError.isAndTrue(GameErrorCode.ITEM_NOT_ENOUGH,"道具不足", !ItemManager.checkGoodsByCid(player, goods));

		// 赠送
		Map<String, Object> in = Maps.newHashMap();
		in.put(EventConditionKey.CONDITION_TYPE, EventConditionType.DONATE_GIFT);
		in.put(EventConditionKey.ROLE_CID, role.getCid());
		in.put(EventConditionKey.GIFT_CID, msg.getItemCid());
		GameEvent event = new GameEvent(player, EventType.ROLE_CHANGE, in);
		GameEventPlugin.syncSubmit(event);


		LogDsp log = LogDsp.newBuilder(GoodsDsp.DONATE).targetTag(role.getCid());
		// 对指定精灵使用道具
		ItemManager.useGoodsByCid(player, null, role, goods, null,log);
		
		
		return new byte[0];
	}

	@Override
	public byte[] dress(ISession session, Dress msg) throws AbstractLogicModelException {
		long roleId= Long.valueOf(msg.getRoleId());
		long dressId = Long.valueOf(msg.getItemId());
		
		Player player = session.getAttr(SessionConstent.PLAYER);
		
		
		Role equipRole = RoleCache.me().getById(roleId);
		ToolError.isAndTrue(GameErrorCode.NOT_FOND_ROLE,"精灵不存在", equipRole==null);
		
		DressVO dressVO = (DressVO) ItemCache.me().getById(dressId);
		ToolError.isAndTrue(GameErrorCode.NOT_FOND_DRESS,"时装不存在", dressVO==null);
		
		RoleCfg cfg = equipRole.getRoleProxy().getConfig();
		boolean equip = ArrayUtils.contains(cfg.getDress(), dressVO.getCid());
		ToolError.isAndTrue(GameErrorCode.NOT_EQUIP_DRESS,"精灵和时装不匹配", !equip);
		
		
		Role oldRole = null;
		long oldRoleId = dressVO.getRoleId();
		if (oldRoleId != 0) {
			oldRole = RoleCache.me().getById(oldRoleId);
			oldRole.getRoleProxy().setDressVO(null);
		}
		
		
		dressVO.setRoleId(equipRole.getId());
		dressVO.update();
		
		// 卸下老的时装
		DressVO oldDressVO = equipRole.getRoleProxy().getDressVO();
		if (oldDressVO!=null) {
			oldDressVO.setRoleId(0);
			oldDressVO.update();
		}

		Map<String, Object> in = Maps.newHashMap();
		in.put(EventConditionKey.CONDITION_TYPE, EventConditionType.DRESS);
		in.put(EventConditionKey.ROLE_CID, equipRole.getCid());
		in.put(EventConditionKey.DRESS_ID, dressVO.getCid());
		GameEvent event = new GameEvent(player, EventType.EQUIPMENT, in);
		GameEventPlugin.syncSubmit(event);

		equipRole.getRoleProxy().setDressVO(dressVO);
		
		ItemMsgBuilder.sendItemMsg(player, ChangeType.UPDATE, dressVO,oldDressVO);
		
		RoleMsgBuilder.sendRoleMsg(player, ChangeType.UPDATE, equipRole,oldRole);
//		player.sendMsg(MessageManager.newMesssage(ItemBO.pushItem, ProtoUnit.toByte(dressInfo)));
//		ItemList.Builder itemChange = ItemList.newBuilder();
		
		return new byte[0];
//		return ItemMsgBuilder.createItemInfo(type, item);
	}

	@Override
	public byte[] switchRole(ISession session, SwitchRole msg) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);
		
		Role role = RoleCache.me().getById(Long.valueOf(msg.getRoleId()));
		
		ToolError.isAndTrue(GameErrorCode.NOT_FOND_ROLE,"精灵不存在", role==null);
		
		ToolError.isAndTrue(GameErrorCode.ROLE_STATUS_ERROR,"状态错误", role.getStatus() == RoleConstant.STATUS_USE);
		
		
		List<Role> roles  = new ArrayList<>(2);
		
		Role oldRole = player.getPlayerProxy().getCurrentRole();
		oldRole.setStatus(RoleConstant.STATUS_DEFAULT);
		oldRole.update();
//		roles.add(oldRole);
		
		role.setStatus(RoleConstant.STATUS_USE);
		player.getPlayerProxy().setCurrentRole(role);
		role.update();
		roles.add(role);
		
//		RoleMsgBuilder.createRoleInfoList(ChangeType.UPDATE, roles);
		SwitchRoleResult.Builder builder = SwitchRoleResult.newBuilder();
		for (Role r : roles) {
			builder.addRolestatus(RoleStatusInfo.newBuilder().setRoleId(Long.toString(r.getId())).setStatus(r.getStatus()));
		}
		return ProtoUnit.toByte(builder.build());
	}

	@Override
	public byte[] touchRole(ISession session, C2SRoleMsg.TouchRole msg) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);

		boolean haveTouchTimes = ItemManager.checkGoodsByCid(player, MapUtil.of(ItemConstantId.DAILY_TOUCH_ROLE_TIMES,1));
		ToolError.isAndTrue(GameErrorCode.HAVE_NO_TOUCH_TIMES,"触摸次数达到上限",!haveTouchTimes);

		ItemManager.costGoodsByCid(player,MapUtil.of(ItemConstantId.DAILY_TOUCH_ROLE_TIMES,1),LogDsp.newBuilder(GoodsDsp.TOUCH_ROLE), S2CItemMsg.ItemList.newBuilder());
		Role role = player.getPlayerProxy().getCurrentRole();
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"好感度临界点，不能触摸", role.getRoleProxy().isCriticalPoint());

		ItemManager.addGoodsAndPush(player,null,role,MapUtil.of(ItemConstantId.ROLE_FAVOR,1),LogDsp.newBuilder(GoodsDsp.TOUCH_ROLE));

		return new byte[0];
	}

	@Override
	public byte[] changeRoom(ISession session, C2SRoleMsg.ChangeRoom msg) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);
		Role role = RoleCache.me().getByCidPlayerId(msg.getRoleCid(),player.getId());
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"更换房间：roleCid错误,role == null",role == null);
		Item item = ItemCache.me().getItemCacheProxy().getByPlayerIdCid(player.getId(),msg.getRoomCid());
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"更换房间：roomCid错误,room == null",item == null);
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"更换房间：roomCid错误,!(item instanceof RoomVO) ",!(item instanceof RoomVO));

		RoomVO room = (RoomVO) item;
//		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"更换房间：房间不是空置状态",room.getRoleId() != 0);

		int roomBelongToRoleId = room.getCfg().getBelongToRole();
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"更换房间：看板娘与房间不匹配",roomBelongToRoleId!= 0 && roomBelongToRoleId != role.getCid());

		List<Role> roleList = RoleManager.changeRoom(role,room);
		RoleMsgBuilder.sendRoleMsg(player, ChangeType.UPDATE, roleList.toArray(new Role[]{}));
		return new byte[0];
	}

	@Override
	public byte[] unlockRoom(ISession session, C2SRoleMsg.UnlockRoom msg) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);
		int roomCid = msg.getRoomCid();
		RoomCfg roomCfg = RoomCfgCache.me().getById(roomCid);
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"解锁房间：roomCid错误,roomCfg == null",roomCfg == null);
		ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"解锁房间：该房间已经解锁",ItemCache.me().getItemCacheProxy().getByPlayerIdCid(player.getId(),roomCid) != null);

		RoleManager.unlockRoom(player,roomCfg);

		return new byte[0];
	}
}
